#include "RtspServer.h"
#include "RtspServerWorker.h"
#include "MediaSession.h"
#include "ffmpeg_pusher.h"

namespace jlh {

	std::shared_ptr<RtspServer> RtspServer::Create()
	{
		std::shared_ptr<RtspServer> server(new RtspServer);
		return server;
	}

	RtspServer::RtspServer(QObject *parent)
		: QObject(parent)
	{
		rtsp_worker_.reset(new RtspServerWorker, [](RtspServerWorker* p) { p->deleteLater(); });
		rtsp_worker_->moveToThread(&worker_thread_);
		worker_thread_.start();
	}

	RtspServer::~RtspServer()
	{
	}

	void RtspServer::Start(const char* ip, uint16_t port)
	{
		std::lock_guard<std::mutex> l(mutex_);
		if (rtsp_worker_)
			rtsp_worker_->Start(ip, port);
	}

	void RtspServer::Stop()
	{
		std::lock_guard<std::mutex> l(mutex_);
		if (rtsp_worker_)
			rtsp_worker_->Stop();
		rtsp_worker_.reset();
	}

	MediaSessionId RtspServer::AddSession(MediaSession* session)
	{
		{
			std::lock_guard<std::mutex> l(mutex_);
			if (rtsp_worker_)
				return rtsp_worker_->AddSession(session);
		}

		return 0;
	}

	bool RtspServer::PushFrame(MediaSessionId sessionId, MediaChannelId channelId, std::shared_ptr<uint8_t>& data, int frame_size, int64_t timestamp)
	{
		AVFrame f(frame_size);
		if (channel_0 == channelId)
		{
			f.size = frame_size - 4;	//Startcode
			f.type = IsKeyFrame(data.get(), frame_size) ? VIDEO_FRAME_I : VIDEO_FRAME_P;
			f.timestamp = timestamp;
			memcpy(f.buffer.get(), data.get() + 4, frame_size - 4);
		}
		else if(channel_1 == channelId)
		{
			f.timestamp = timestamp;
			f.type = AUDIO_FRAME;
			f.size = frame_size;
			memcpy(f.buffer.get(), data.get(), frame_size);
		}
		else
		{
			return false;
		}
		{
			std::lock_guard<std::mutex> l(mutex_);
			if (rtsp_worker_)
				return rtsp_worker_->PushFrame(sessionId, channelId, f);
		}
		return false;
	}

}